package com.ruoyi.project.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.domainenum.FinRecordVoucherStatus;
import com.ruoyi.common.domainenum.FinSubjectType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.common.StaticField;
import com.ruoyi.project.common.StaticMethod;
import com.ruoyi.project.domain.FinPackage;
import com.ruoyi.project.domain.FinRecordVoucher;
import com.ruoyi.project.domain.FinSubjectMonth;
import com.ruoyi.project.service.IFinPackageService;
import com.ruoyi.project.service.IFinRecordVoucherService;
import com.ruoyi.project.service.IFinSubjectMonthService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.SecurityUtils;
import javax.annotation.Resource;
import com.ruoyi.project.mapper.FinSubjectMapper;
import com.ruoyi.project.domain.FinSubject;
import com.ruoyi.project.service.IFinSubjectService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 科目Service业务层处理
 *
 * @author abel
 * @date 2024-10-15
 */
@Service
public class FinSubjectServiceImpl implements IFinSubjectService
{
    @Resource
    private FinSubjectMapper finSubjectMapper;
    @Resource
    private IFinPackageService finPackageService;
    @Resource
    private IFinSubjectMonthService finSubjectMonthService;
    @Resource
    private IFinRecordVoucherService finRecordVoucherService;
    @Resource
    private ISysUserService sysUserService;
    /**
     * 查询科目
     *
     * @param id 科目ID
     * @return 科目
     */
    @Override
    public FinSubject selectFinSubjectById(Long id)
    {
        return finSubjectMapper.selectById(id);
    }

    /**
     * 获取科目，获取不到数据抛错
     *
     * @param id 科目ID
     * @return 科目
     */
    @Override
    public FinSubject getFinSubjectById(Long id)
    {
        FinSubject finSubject = finSubjectMapper.selectById(id);
        if(finSubject == null){
            throw new ServiceException("科目id不正确，没有找到相关数据！");
        }
        return finSubject;
    }

    /**
     * 查询科目列表
     *
     * @param finSubject 科目
     * @return 科目
     */
    @Override
    public List<FinSubject> selectFinSubjectList(FinSubject finSubject)
    {
        return finSubjectMapper.selectFinSubjectList(finSubject);
    }

    /**
     * 新增科目
     *
     * @param finSubject 科目
     * @return 结果
     */
    @Override
    @Transactional
    public int insertFinSubject(FinSubject finSubject)
    {
        StaticMethod.setCreateField(finSubject,SecurityUtils.getUserId(),SecurityUtils.getUsername());
        finSubject.setHasDefault(false);
        if(finSubject.getParentId()!=null){
            FinSubject parent = this.getFinSubjectById(finSubject.getParentId());
            finSubject.setParentName(parent.getName());
            finSubject.setParentCode(parent.getCode());
            finSubject.setSubjectLevel(parent.getSubjectLevel()+1);
        }else {
            finSubject.setSubjectLevel(1);
        }
        int res = finSubjectMapper.insert(finSubject);
        FinPackage finPackage = finPackageService.getFinPackageById(finSubject.getPackageId());
        finSubjectMonthService.createBySubject(finSubject,finPackage.getCurrentYear(),finPackage.getCurrentMonth());
        return res;
    }

    /**
     * 修改科目
     *
     * @param finSubject 科目
     * @return 结果
     */
    @Override
    @Transactional
    public int updateFinSubject(FinSubject finSubject)
    {
        StaticMethod.setUpdateField(finSubject,SecurityUtils.getUserId(),SecurityUtils.getUsername());
        if(finSubject.getParentId()!=null){
            FinSubject parent = this.getFinSubjectById(finSubject.getParentId());
            finSubject.setParentName(parent.getName());
            finSubject.setSubjectLevel(parent.getSubjectLevel()+1);
        }else {
            finSubject.setSubjectLevel(1);
        }
        int res = finSubjectMapper.updateById(finSubject);
        finSubjectMonthService.updateBySubject(finSubject);
        return res;
    }

    /**
     * 批量删除科目
     *
     * @param ids 需要删除的科目ID
     * @return 结果
     */
    @Override
    public int deleteFinSubjectByIds(Long[] ids)
    {
        for(Long id:ids){
            deleteFinSubjectById(id);
        }
        return ids.length;
    }

    /**
     * 删除科目信息
     *
     * @param id 科目ID
     * @return 结果
     */
    @Override
    public int deleteFinSubjectById(Long id)
    {
        //系统默认不能删除，如果有child不能删除。
        FinSubject finSubject = this.getFinSubjectById(id);
        if(finSubject.getHasDefault()){
            throw new ServiceException("系统默认科目，不能删除！");
        }
        if(finSubjectMapper.countByParentId(id)>0){
            throw new ServiceException("存在二级科目，不能删除！");
        }
        return finSubjectMapper.deleteFinSubjectById(id);
    }

    @Override
    public void syncSubjectMonth(Long packageId) {
        List<FinSubject> subjectList = finSubjectMapper.listByPackageId(packageId);
        FinPackage finPackage = finPackageService.getFinPackageById(packageId);
        subjectList.forEach(finSubject -> {
            finSubjectMonthService.createBySubject(finSubject,finPackage.getCurrentYear(),finPackage.getCurrentMonth());
        });
    }

    @Override
    public List<TreeSelect> listTreeSelectByPackageId(Long packageId) {
        List<FinSubject> subjectList = finSubjectMapper.listByPackageId(packageId);
        Map<Long,TreeSelect> idMap = new HashMap<>();
        List<TreeSelect> res = new ArrayList<>();
        subjectList.forEach(finSubject -> {
            TreeSelect treeSelect = genTreeSelect(finSubject);
            if(finSubject.getParentId()==null || finSubject.getParentId()==0){
                res.add(treeSelect);
            }else {
                TreeSelect parent = idMap.get(finSubject.getParentId());
                if(parent.getChildren()==null){
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(treeSelect);
            }
            idMap.put(treeSelect.getId(),treeSelect);
        });
        return res;
    }

    private TreeSelect genTreeSelect(FinSubject finSubject){
        TreeSelect treeSelect = new TreeSelect();
        treeSelect.setId(finSubject.getId());
        treeSelect.setValue(finSubject.getId());
        String label = finSubject.getCode() + " "+finSubject.getName();
        treeSelect.setLabel(label);
        return treeSelect;
    }

    @Override
    public void moveSY(Long packageId,Long toSubjectId) {
        FinPackage finPackage = finPackageService.getFinPackageById(packageId);
        FinSubjectMonth monthQuery = new FinSubjectMonth();
        monthQuery.setPackageId(ServletUtils.getPackageId());
        String yearAndMonth = StaticMethod.genYearAndMonth(finPackage.getCurrentYear(),finPackage.getCurrentMonth());
        monthQuery.setYearAndMonth(yearAndMonth);
        monthQuery.setSubjectType(FinSubjectType.SY);
        List<FinSubjectMonth> list = finSubjectMonthService.selectFinSubjectMonthList(monthQuery);
        //1、按父节点-》子节点排序，没有子节点的节点做结转分录
        //2、结转分录生成
        //3、期末余额置为0

        List<FinSubjectMonth> listValue = new ArrayList<>();
        List<FinSubjectMonth> moveSubjectList = new ArrayList<>();
        List<FinSubjectMonth> parentSubjectList = new ArrayList<>();
        Set<String> parentIdSet = new HashSet<>();

        list.forEach(finSubjectMonth -> {
           if(finSubjectMonth.getMonthJieValue().compareTo(BigDecimal.ZERO)>0 || finSubjectMonth.getMonthDaiValue().compareTo(BigDecimal.ZERO)>0){
               listValue.add(finSubjectMonth);
               if(finSubjectMonth.getSubjectParentId()!=null){
                    parentIdSet.add(finSubjectMonth.getSubjectParentId().toString());
               }
           }
        });
        listValue.forEach(m->{
            if(parentIdSet.contains(m.getId().toString())){
                parentSubjectList.add(m);
            }else {
                moveSubjectList.add(m);
            }
        });
        FinSubject toSubject = finSubjectMapper.selectById(toSubjectId);
        FinSubjectMonth toSubjectMonth = finSubjectMonthService.findBySubjectInfo(toSubject,finPackage.getCurrentYear(),finPackage.getCurrentMonth());

        FinRecordVoucher recordVoucher = new FinRecordVoucher();
        int maxTag = finRecordVoucherService.getMaxRecordNo(finPackage.getId(), StaticField.RECORD_TAG_JI,finPackage.getCurrentYear(),finPackage.getCurrentMonth());
        recordVoucher.setMonthValue(finPackage.getCurrentMonth());
        recordVoucher.setYearValue(finPackage.getCurrentYear());
        recordVoucher.setYearAndMonth(yearAndMonth);
        SysUser sysUser = sysUserService.selectUserById(SecurityUtils.getUserId());
        StaticMethod.setCreateField(recordVoucher,sysUser.getUserId(),sysUser.getNickName());
        recordVoucher.setRecordBy(sysUser.getNickName());
        recordVoucher.setRecordId(sysUser.getUserId());
        recordVoucher.setRecordNo(maxTag);
        recordVoucher.setRecordDate(new Date());
        recordVoucher.setRecordTag(StaticField.RECORD_TAG_JI);
        recordVoucher.setStatus(FinRecordVoucherStatus.CHECKED);
        BigDecimal jieValue = BigDecimal.ZERO;
        BigDecimal daiValue = BigDecimal.ZERO;






    }
}
